package org.leiyang.netty.listener;

import com.alibaba.fastjson.JSON;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.util.CharsetUtil;
import org.leiyang.common.dtos.Message;
import org.leiyang.common.dtos.MessageType;
import org.leiyang.common.dtos.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Mono;

import java.util.function.Consumer;

/**
 * 对netty来的消息，进行过滤处理
 */
public interface INettyMsgFilter {
    Logger logger = LoggerFactory.getLogger(INettyMsgFilter.class);

    /**
     * 按照{@link Message}的{@link MessageType}进行分类处理
     * @param message 消息内容
     * @param ctx ctx
     * @param serverIp server地址
     * @param port 端口
     * @param httpFormat 是否属于http格式的消息
     * @return 是否继续执行后面的filter
     */
    Mono<Boolean> chain(Message message, ChannelHandlerContext ctx, String serverIp, String port, Boolean httpFormat);

    /**
     * 发送响应给WS客户端
     * @param ctx ctx
     * @param reps 响应数据
     * @param funInCallBack 回调里执行的操作
     * @param httpFormat 是否属于http格式的消息
     */
    default void sendResponse(ChannelHandlerContext ctx, R<Message> reps, Consumer<ChannelHandlerContext> funInCallBack, Boolean httpFormat) {
        // 表示非http格式，那就是发送TEXT格式
        final String repsStr = JSON.toJSONString(reps);
        if(!httpFormat) {
            //这里发送文本格式消息
            WebSocketFrame content = new TextWebSocketFrame(repsStr);
            ctx.writeAndFlush(content).addListener(future -> {
                if (future.isSuccess()) {
                    logger.info("Msg Server端已发送消息到客户端: {}", repsStr);
                    funInCallBack.accept(ctx);
                    return;
                }
                logger.error("Msg Server端发送响应是否成功: {}, 异常信息: ", future.isSuccess(), future.cause());
            });
            return;
        }
        //表示http格式的
        byte[] content = repsStr.getBytes(CharsetUtil.UTF_8);
        FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
        response.content().writeBytes(content);
        response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
        response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
        // 发送响应
        ctx.writeAndFlush(response).addListener(future -> {
            if (future.isSuccess()) {
                logger.info("Msg Server端已发送消息到客户端: {}", reps);
                funInCallBack.accept(ctx);
            }
            logger.info("Msg Server端发送响应是否成功: {}, 异常信息: ", future.isSuccess(), future.cause());
        });
    }
}
